package cn.huapu.power.energy.cfg;

import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.*;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Mybatis的事物配置，主要是将service的方法进行事务管理
 * 考虑到数据库主从的配置，建议从数据库url配置入手，故暂时不进行使用 
 * @author xxx
 *
 */
//@Configuration
public class TxAdviceInterceptor {
	private static final int TX_METHOD_TIMEOUT = 5;
	private static final String AOP_POINTCUT_EXPRESSION = "execution (* cn.huapu.power..service.*.*(..))";

	//@Bean("txSource")
	public TransactionAttributeSource transactionAttributeSource() {
		NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
		RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
		readOnlyTx.setReadOnly(true);
		readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
		RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();
		requiredTx.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
		requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
		requiredTx.setTimeout(TX_METHOD_TIMEOUT);
		Map<String, TransactionAttribute> txMap = new HashMap<>();
		txMap.put("get*", readOnlyTx);
		txMap.put("query*", readOnlyTx);
		txMap.put("*", requiredTx);
		source.setNameMap(txMap);
		return source;
	}

	/**
	 * @Bean public Advisor txAdviceAdvisor() { AspectJExpressionPointcut pointcut =
	 *       new AspectJExpressionPointcut();
	 *       pointcut.setExpression(AOP_POINTCUT_EXPRESSION); return new
	 *       DefaultPointcutAdvisor(pointcut, txAdvice()); }
	 */
	//@Bean
	public AspectJExpressionPointcutAdvisor pointcutAdvisor(TransactionInterceptor txInterceptor) {
		AspectJExpressionPointcutAdvisor pointcutAdvisor = new AspectJExpressionPointcutAdvisor();
		pointcutAdvisor.setAdvice(txInterceptor);
		pointcutAdvisor.setExpression(AOP_POINTCUT_EXPRESSION);
		return pointcutAdvisor;
	}

	/* 事务拦截器 */
	//@Bean("txInterceptor")
	TransactionInterceptor getTransactionInterceptor(PlatformTransactionManager tx) {
		return new TransactionInterceptor(tx, transactionAttributeSource());
	}

}
